package emd24.telstudyresources;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.ToggleButton;

/**
 * This class represents the screen where the user answers a question. It consists
 * of a question, five answers for each questions, buttons to navigate between
 * questions, and a marking feature.
 * 
 * @author Evan Dyke
 *
 */
public class QuestionActivity extends Activity {

	private ToggleButton[] answerButtons;
	private TextView questionNumber;
	private WebView questionText;
	private TextView timerText;
	private Quiz quiz;
	private boolean mark;
	private boolean studyMode;
	private CountDownTimer time;
	private Long millisRemaining;
	private SharedPreferences prefs;

	@SuppressLint("SetJavaScriptEnabled")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bundle b = null;
		// Checks to see if there was a previously saved state
		if(savedInstanceState != null){
			b = savedInstanceState;
		}else{
			b = this.getIntent().getExtras();
		}
		this.studyMode = b.getBoolean("study");
		// Set the layout depending on the mode the user has entered

		if(this.studyMode){
			setContentView(R.layout.activity_question_studymode);
		}else{
			setContentView(R.layout.activity_question);
		}

		// Get values passed from Intent
		this.quiz = b.getParcelable("quiz");


		// Assign UI objects to Activity

		// Configure the web-view
		this.questionText = (WebView) this.findViewById(R.id.questionText);
		this.questionText.getSettings().setJavaScriptEnabled(true);
		this.questionText.getSettings().setBuiltInZoomControls(true);
		prefs = getPreferences(MODE_PRIVATE);
		if (prefs.getString("MathJaxURL","").length() == 0) {
			SharedPreferences.Editor editprefs = prefs.edit();
			editprefs.putString("MathJaxURL", getResources().getString(R.string.mJaxUrl));	
			editprefs.commit();
		}

		ToggleButton[] answerButtons = {(ToggleButton) this.findViewById(R.id.choiceA), 
				(ToggleButton) this.findViewById(R.id.choiceB), (ToggleButton) this.findViewById(R.id.choiceC),
				(ToggleButton) this.findViewById(R.id.choiceD), (ToggleButton) this.findViewById(R.id.choiceE)};
		this.answerButtons = answerButtons;
		this.questionNumber = (TextView) this.findViewById(R.id.questionNumber);
		this.timerText = (TextView) this.findViewById(R.id.timerText);
		//setQuestion(quiz.getCurrQuestionIndex());
		// Next Button
		this.findViewById(R.id.next).setOnClickListener(new OnClickListener() {
			public void onClick(View v){
				// Go to the review screen if at the end of the quiz
				if (!studyMode && quiz.getCurrQuestionIndex() == quiz.getNumQuestions()-1) {
					//Store current answer
					saveAnswer();
					reviewScreen();
				}
				else{
					if(mark){
						saveAnswer();
						int next = quiz.getNextMarked(quiz.getCurrQuestionIndex());
						if(next == -1){
							reviewScreen();
						}
						else{
							setQuestion(next);
						}
					}
					else{
						if(!studyMode){
							saveAnswer();
						}
						setQuestion(quiz.getCurrQuestionIndex() + 1);
					}
				}
			}
		});

		// Previous Button
		this.findViewById(R.id.previous).setOnClickListener(new OnClickListener() {
			public void onClick(View v){
				if(mark){
					saveAnswer();
					setQuestion(quiz.getPrevMarked(quiz.getCurrQuestionIndex()));
				}
				else{
					if(!studyMode){
						saveAnswer();
					}
					setQuestion(quiz.getCurrQuestionIndex() - 1);	
				}
			}
		});
		// Create button listeners for answer buttons
		for(int i = 0; i < this.answerButtons.length; i++){
			answerButtons[i].setOnClickListener(new OnClickListener() {
				public void onClick(View v){
					// Select the answer to the question
					select(v.getId());
				}
			});
		}


		if(this.studyMode){
			// Set appropriate listeners if in Study Mode
			this.findViewById(R.id.solution).setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View arg0) {
					saveAnswer();
					displaySolutionDialog();
				}			
			});

		}else{
			// Set listeners if taking a quiz			
			this.mark = b.getBoolean("mark");
			Long duration = b.getLong("time");

			// Set the timer 
			this.time = new CountDownTimer(duration, 1000){

				@Override
				public void onFinish() {
					endQuiz();
				}

				@Override
				public void onTick(long msUntilFinished) {
					// Format the time for the TextView in H:MM:SS
					millisRemaining = msUntilFinished;
					long hours = msUntilFinished / (1000 * 3600);
					long minutes = msUntilFinished / (1000 * 60) % 60;
					long seconds = (msUntilFinished / 1000) % 60;
					timerText.setText(hours + ":" + ((minutes < 10) ? "0" : "") +  minutes + ":" + 
							((seconds < 10) ? "0" : "") +  seconds);		
				}

			}.start();
		}
		setQuestion(b.getInt("qIndex"));

	}
	@Override
	protected void onDestroy(){
		if(!this.studyMode){
			Log.e("Timer event","Timer cancelled from QuestionActivity");
			this.time.cancel();
		}
		super.onDestroy();
	}
	@Override
	protected void onSaveInstanceState(Bundle outState){
		saveAnswer();
		if(!this.studyMode){
			outState.putLong("time", this.millisRemaining);	
		}
		outState.putParcelable("quiz", this.quiz);
		outState.putInt("qIndex", this.quiz.getCurrQuestionIndex());
		outState.putBoolean("study", this.studyMode);
		outState.putBoolean("mark", this.mark);
		super.onSaveInstanceState(outState);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_question, menu);
		return true;
	}
	/**
	 * Overrides the back button so a dialog box can be displayed
	 * 
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK && !this.studyMode)) {
			backKeyExit();
		}
		return super.onKeyDown(keyCode, event);
	}
	/**
	 * Displays a dialog box asking the user if they are sure
	 * they want to exit the quiz. If the user selects yes, the
	 * activity is finished.
	 * 
	 */
	private void backKeyExit(){
		new AlertDialog.Builder(this).setMessage(R.string.quiz_exit).setCancelable(false).
		setPositiveButton("Yes", new DialogInterface.OnClickListener() {

			// Set listener for when yes button is clicked, exit activity
			public void onClick(DialogInterface arg0, int arg1) {
				finish();
			}
		}).setNegativeButton("No", new DialogInterface.OnClickListener() {

			// Set listener for no button
			public void onClick(DialogInterface arg0, int arg1) {
			}
		}).show();

	}
	/**
	 * Changes the question displayed on the layout.
	 * 
	 * @param index of question to set
	 */
	private void setQuestion(int index){

		// Check to see if valid index		
		if(index >= 0 && index < this.quiz.getNumQuestions()){
			questionText.clearView();
			// Load the new question to the screen
			Question question = this.quiz.getQuestionAt(index);
			this.quiz.setCurrQuestionIndex(index);
			this.questionNumber.setText("Question " + (index + 1) + " of " + 
					this.quiz.getNumQuestions());

			long startTime = System.currentTimeMillis();
			questionText.loadUrl(question.getQuestionText());
			long endTime = System.currentTimeMillis();

			Log.e("Time loading", endTime- startTime + " milliseconds");

			// Sets the answers and deselects all buttons
			for(int choice = 0; choice < this.answerButtons.length; choice++){
				this.answerButtons[choice].setChecked(false);
			}

			// If the user selected an answer to the question, indicate it
			if(!this.studyMode && this.quiz.getCurrentQuestion().getSelectedAnswer() != -1){
				this.answerButtons[this.quiz.getCurrentQuestion().getSelectedAnswer()].setChecked(true);
			}
			// Change button settings

			// If the question was marked, indicate it on the screen
			if(!this.studyMode){
				((ToggleButton)this.findViewById(R.id.mark)).
				setChecked(this.quiz.getCurrentQuestion().isMarked());
			}

			// Hide previous button if at the first question (or no previously marked)
			if(index == 0 || (this.mark && quiz.getPrevMarked(this.quiz.getCurrQuestionIndex()) == -1)){
				this.findViewById(R.id.previous).setVisibility(View.GONE);
			}
			else{
				this.findViewById(R.id.previous).setVisibility(View.VISIBLE);
			}
			// Hide next button if at end if in study mode
			if(this.studyMode&& (index == this.quiz.getNumQuestions() - 1 || 
					(this.mark && quiz.getPrevMarked(this.quiz.getCurrQuestionIndex()) == -1))){
				this.findViewById(R.id.next).setVisibility(View.GONE);
			}else{
				this.findViewById(R.id.next).setVisibility(View.VISIBLE);
			}
		}else{
			return;	
		}
	}

	/**
	 * Checks the button with a given ID and deselects all other
	 * buttons
	 * 
	 * @param id int id of ToggleButton to select
	 */
	private void select(int id){

		for(int i = 0; i < this.answerButtons.length; i++){
			if(this.answerButtons[i].getId() != id){
				this.answerButtons[i].setChecked(false);
			}
			else{
				this.answerButtons[i].setChecked(true);
			}
		}
	}
	/**
	 * Opens up the review screen.
	 * 
	 */
	private void reviewScreen(){
		Intent review = new Intent(this,ReviewActivity.class);
		review.putExtra("quiz", this.quiz);
		review.putExtra("time",this.millisRemaining);
		startActivity(review);
		finish();
	}
	private void endQuiz(){
		Intent result = new Intent(this,ResultsActivity.class);
		result.putExtra("quiz",this.quiz);
		startActivity(result);
		finish();
	}
	/**
	 * Saves the data from the user interface into the quiz.
	 * 
	 */
	private boolean saveAnswer(){
		boolean answerPicked = false;
		for(int i = 0; i < this.answerButtons.length; i++){
			if(this.answerButtons[i].isChecked()){
				this.quiz.getCurrentQuestion().setSelectedAnswer(i);
				answerPicked = true;
			}
		}
		if(!this.studyMode){
			this.quiz.getCurrentQuestion().setMarked(((ToggleButton)this.findViewById(R.id.mark)).isChecked());
		}
		return answerPicked;
	}
	/**
	 * Displays a dialog informing the user if the selected the right answer
	 * 
	 */
	private void displaySolutionDialog() {
		boolean answerPicked = saveAnswer();
		String msg;
		if(this.quiz.getCurrentQuestion().isCorrect()){
			msg = "Correct!";
		}else if (answerPicked == false) {
			msg = "Please choose your answer.";
		}else {
			msg = "Wrong! The correct answer was " + (char) (this.quiz.getCurrentQuestion().getCorrectAnswer() + 65);
		}

		if(answerPicked){
			new AlertDialog.Builder(this).setMessage(msg).
			setPositiveButton("Solution", new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface arg0, int arg1) {
					viewSolution();
				}
			}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {

				}
			}).show();
		}else{
			new AlertDialog.Builder(this).setMessage(msg).
			setNeutralButton("Cancel", new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface arg0, int arg1) {

				}
			}).show();
		}
	}
	/**
	 * Shows the solution for the current question in a new activity.
	 * 
	 */
	private void viewSolution(){
		Intent i = new Intent(this,SolutionActivity.class);
		i.putExtra("question", this.quiz.getCurrentQuestion());
		startActivity(i);
	}
}